/*
 * bspImitativeUart.c
 *
 *  Created on: 2017年9月20日
 *      Author: Administrator
 */
/* Driver Header files */
#include <string.h>
#include <stdio.h>
#include "bspTimer.h"
#include "bspImitativeUart.h"

volatile teVuartStatus egVuartStatus;
volatile tsVuartDevice tgVuartDev;
tsVuart tgVuart;

#define TIMER_VUART	TIMER2

/* UART设置为空闲状态 */
static void vSetVuartIdle(void)
{
    V_TX_HI();
    vTimerStop(TIMER_VUART);	//关闭定时器
	
    egVuartStatus = V_UART_IDLE;
    tgVuartDev.usCountByte = 0;
}

/* 用定时器模拟UART */
static void vCallBackSendTimer(void)
{
	LED_TOGGLE();
    switch(egVuartStatus)
    {
        case V_UART_IDLE:
        {
            vSetVuartIdle();
        }return;

        case V_UART_SEND_START: /* 发送起始 */
        {
            egVuartStatus = V_UART_SEND_DATA_BIT;  /* 发送数据 */
            V_TX_LOW();              //start bit
        }break;

        case V_UART_SEND_DATA_BIT:
        {
            if(tgVuartDev.ucData & tgVuartDev.ucCountBit)
                V_TX_HI();
            else
                V_TX_LOW();

            tgVuartDev.ucCountBit <<= 1;
            if(tgVuartDev.ucCountBit == 0x00)
                egVuartStatus = V_UART_SEND_DATA_BYTE;
        }break;


        case V_UART_SEND_DATA_BYTE: /* 发送停止位,并将数据指向下一个字节 */
        {
            V_TX_HI();  /* stop bit */
            if(++tgVuartDev.usCountByte < tgVuart.usSendSize)
            {
                tgVuartDev.ucCountBit = 1;
                tgVuartDev.ucData = tgVuart.ucSendBuf[tgVuartDev.usCountByte];
                egVuartStatus = V_UART_SEND_START;  /* 发送起始 */
            }
            else
            {
                vSetVuartIdle();
            }    
        }break;	
    }
}

/* 模拟UART初始化,最高波特率57600,在此波特率下还有可能乱码,建议使用38400 */
void vImitativeUartInit(uint32_t uiBaudRate)
{
    /* GPIO初始化  */
	rcu_periph_clock_enable(RCU_GPIOB);
	//LED
	gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO_PIN_13);
	gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13);	
	LED_HI();
	//TXD
	gpio_mode_set(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, GPIO_PIN_15);
	gpio_output_options_set(GPIOB, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_15);		
	V_TX_HI();
	
	/* Timer初始化 */
	vInitTimer(TIMER_VUART, uiBaudRate, vCallBackSendTimer);
	
    vSetVuartIdle();
}

/* 模拟UART发送 */
void vUartSend(uint8_t *pucBuf, uint16_t usSize)
{
    if(pucBuf == NULL)
        return;

	if(usSize > V_UART_SEND_BUF_SIZE)
		tgVuart.usSendSize = V_UART_SEND_BUF_SIZE;
	else
		tgVuart.usSendSize = usSize;
	memcpy(tgVuart.ucSendBuf, pucBuf, tgVuart.usSendSize);

	tgVuartDev.usCountByte = 0;
	tgVuartDev.ucCountBit = 1;
	egVuartStatus = V_UART_SEND_START;
	tgVuartDev.ucData = tgVuart.ucSendBuf[tgVuartDev.usCountByte];
	
	vTimerStart(TIMER_VUART);
	
	while(egVuartStatus != V_UART_IDLE);
}


/* retarget the C library printf function to the USART */
int fputc(int ch, FILE *f)
{
    vUartSend((uint8_t *)&ch, 1);
    return ch;
}
